Skip to content

Core modernization and single-resolve dependency management - #14

Merged
zeyuyang42 merged 26 commits into
mainfrom
core_modernization
Aug 19, 2026
Merged

Core modernization and single-resolve dependency management#14
zeyuyang42 merged 26 commits into
mainfrom
core_modernization

Conversation

@zeyuyang42

Copy link
Copy Markdown
Collaborator

Summary

Brings 26 commits of core modernization and dependency-management work onto main. This is a refactor/tooling branch, not a feature branch — no audio algorithm was rewritten. main is fully contained in this branch, so it merges as a clean fast-forward.

71 files, +2,809 / −1,442. The core/ library is a net reduction (40 files, +910 / −1,078) despite gaining documentation.

What's in it

C++ modernization in core/ — type vocabulary consolidated in types.h (Complex/FFTBuffer/SpecBuffer dropped in favour of Samples and fftw_complex); PairSpeakerPair; the stringly-typed Mode split into strongly-typed GenMode / TriggerMode; raw new/deleteunique_ptr; #defineinline constexpr inside namespace zerr; raw loops replaced; const/noexcept applied throughout; metadata boilerplate (name/category/description statics) removed.

PI was renamed to pi deliberately — it collides with a macro in the Max headers.

Dependency consolidationcore/, puredata/ and maxmsp/ each ran their own conan install, so three independent profile resolutions could disagree. That is how the core came to be compiled for a different macOS deployment target than the wrappers linked against (libzerr_core.a at minos 15.0 inside an external declaring minos 11.0). Now one root conanfile.txt, one resolve into build/, consumed three ways: conan_toolchain.cmake for core and Max/MSP, conandeps.mk for PureData. Committed profiles in profiles/ (macos, linux, mingw) make it reproducible, and recipe revisions are pinned because both libraries need a ConanCenter revision that survives CMake 4.

build.sh — gained a deps target, staleness detection that discards any build tree or installed archive configured against a different or older toolchain (a CMakeCache silently ignores a newly passed CMAKE_TOOLCHAIN_FILE, which is how the deployment-target pin went missing in the first place), and Windows support for MSYS2/MinGW shells.

Wrapper fixesmc.zerr.envelopes~ called object_free() before dsp_setup(), reaching dsp_free() on an un-set-up t_pxobject from any bad mode or config argument; both envelopes wrappers leaked their ZerrEnvelopes on initialize() failure; zerr_envelopes~ leaked two strdup'd strings on every instantiation; puredata/Makefile's clean guard matched make clean all and then built with empty CONAN_* variables.

Docs — Doxygen setup reorganized under docs/, plus design docs in docs/design/: a repo audit, a project status report, a change comparison report (written at 22 commits, so it predates the dependency work), and a dependency-fallback reference recording which non-conan resolve routes are viable and what each one breaks.

Verification

CI dispatched against the branch head: run 32297202438 — macOS, Linux and Windows all green on 75b19d7.

Worth noting from that run: macOS and Windows both build fftw and yaml-cpp from source, which is exactly what fails under CMake 4 without the pinned revisions — so the pin is exercised every run, not just theoretically load-bearing. The macOS job logs CMAKE_OSX_DEPLOYMENT_TARGET set to 10.13, confirming the pin reaches CI.

Locally, from a fully clean tree: core at minos 11.0, 4 PureData externals, 5 Max/MSP externals, no shared yaml-cpp/fftw in the linked output.

Known and deferred — not introduced here

  • Three pre-existing audio-path bugs, found by review and deliberately left for a dedicated debugging pass: zerr_envelopes_perform64 calls a perform() that can throw, so an exception can reach std::terminate from Max's audio thread; EnvelopeGenerator::processFunc is a pointer-to-member read uninitialized, defeating its own if (processFunc) guard; and the !yaml_found path leaks its allocated object.
  • The Windows build.sh path is written to CI parity but unexercised on real hardware. CI never invokes build.sh. Also, profiles/mingw pins compiler.version=13 while the runners now carry gcc 16.1.0 — it works because the libstdc++11 ABI is stable, but the setting has drifted. Knowingly left open.
  • jack/ remains dead codemeson.build lists ~15 sources that do not exist and the headers reference modules deleted from the core. Untouched by this branch; still advertised in the README.

After merge

This is the first push to main since the workflows were rewritten, and all three trigger on push to main — so merging will fire the core build, the PureData chain that depends on it, and the Doxygen deploy.

🤖 Generated with Claude Code

zeyuyang42 and others added 26 commits February 15, 2026 00:05
Hand-authored status/design doc separated from Doxygen output
(docs/build/) and config (docs/Doxyfile, docs/doxygen-awesome-css).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Detailed diff report of core_modernization vs main under docs/design.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Every target ran its own `conan install`, so zerr_core and the wrappers that
link it could be resolved from different profiles. On macOS that produced a
core built at the host SDK's deployment target and wrappers at 10.6, and the
mismatch surfaced only as linker warnings.

Dependencies are now declared once in the root conanfile.txt and generated
into a single build/ folder: core and Max/MSP consume conan_toolchain.cmake,
PureData consumes conandeps.mk. Committed profiles (macos, linux, mingw) pin
the settings that must agree across targets, and recipe revisions are pinned
because both libraries need a ConanCenter revision that supports CMake 4.

build.sh gains a `deps` target and now discards any build tree or installed
archive configured against a different or older toolchain. A CMakeCache
silently ignores a newly passed CMAKE_TOOLCHAIN_FILE -- which is how the
pinned deployment target went missing to begin with -- and an existing
libzerr_core.a is no proof it was built against the toolchain the wrapper is
about to use.

Also fixes three wrapper faults found while reviewing the above:

- mc.zerr.envelopes~ called object_free() before dsp_setup(), so a bad mode
  or config argument reached dsp_free() on an un-set-up t_pxobject
- both envelopes wrappers leaked the ZerrEnvelopes instance when initialize()
  failed; zerr_envelopes~ additionally leaked two strdup'd strings on every
  instantiation, success included
- puredata/Makefile's clean guard matched `make clean all`, which then built
  with the CONAN_* variables empty and produced a cryptic compiler error
  instead of the intended message

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…olution

Resolve conan dependencies once at the repo root
build.sh already selected profiles/mingw for MSYS2/Git Bash hosts, but it never
matched what the Windows CI jobs actually do, so the path it advertised did not
work:

- Pin -G "MinGW Makefiles". Without it CMake picks a Visual Studio generator
  whenever one is installed and compiles with MSVC against a MinGW toolchain.
- Prefer mingw32-make over the MSYS make, as the PureData Windows job does.
- Discard a build tree whose cached CMAKE_GENERATOR disagrees. Passing -G to a
  directory configured by a different generator is a hard CMake error, not a
  warning, so the existing staleness check had to learn about it.
- Compare the cached CMAKE_TOOLCHAIN_FILE against the native path spelling.
  $TOOLCHAIN comes out of `pwd` as /c/Users/..., while the MSYS layer rewrites
  the argument to C:/Users/... on its way to a native CMake -- a verbatim
  compare can never match, and every run would discard the tree and rebuild the
  core.
- Refuse maxmsp on Windows in the target-validation loop rather than inside
  build_maxmsp, because the dispatcher builds the core library before calling
  the per-target function. A .mxe64 needs MSVC, whose ABI cannot link a
  MinGW-built libzerr_core.a.

The Windows path is written to CI parity but has not been exercised on real
hardware. The branches were verified on macOS with a faked host: profile and
generator selection across Darwin/Linux/MINGW/MSYS/CYGWIN, mingw32-make
preference and fallback, guard ordering for single and multi-target invocations,
and that `-c maxmsp` still cleans.

docs/design/dependency-fallbacks.md replaces the USE_SYSTEM_DEPS fallback that
was assessed and declined. Rather than an untested second resolve path, it
records which non-conan routes are viable and what each one breaks: target names
verified against the generated files (conan exposes fftw as fftw::fftw but its
libraries as FFTW3::* components, with fftw3f/fftw3l siblings of the double
precision target we need), static vs shared, YAML_CPP_STATIC_DEFINE living in
two places, the deployment target, and the CMake 4 floor behind the pinned
recipe revisions.

repo-audit §2.3 is corrected: it claimed improve_deps_manage had been fully
re-applied. The superbuild and the system-deps fallback were never ported, both
deliberately, and the branch also carries two regressions worth recording.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@zeyuyang42
zeyuyang42 merged commit f6babf1 into main Aug 19, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant